#pragma once

#include "Comm.hpp"

const static size_t buffer_default_size = 1024;

class Buffer
{
private:
    const char* Begin() const {  return &(*(_buffer.begin())); }

    // 获取写偏移指针后的空闲空间
    uint64_t GetSizeAfterWrite() const { return _buffer.size() - _writer_idx; }

    // 获取读偏移指针前的空闲空间
    uint64_t GetSizeBeforeRead() const { return _reader_idx; }

    // 确保可写空间足够
    void EnsureWriteSpace(uint64_t len)
    {
        if (GetSizeAfterWrite() >= len) return;
        if (len <= GetSizeBeforeRead() + GetSizeAfterWrite())
        {
            uint64_t readable_size = GetSizeOfReadableData();
            // std::copy(GetReadPos(), GetReadPos() + readable_size, Begin());
            memmove((void*)Begin(), GetReadPos(), GetSizeOfReadableData());
            _reader_idx = 0;
            _writer_idx = readable_size;
            LOG(DEBUG, "数据移动完成，无扩容！\n");
        }
        else
        {
            _buffer.resize(_writer_idx + len);
            LOG(DEBUG, "扩容完成，当前缓冲区空间大小：%ld\n", _buffer.capacity());
        }
    }

public:
    Buffer() : _reader_idx(0), _writer_idx(0), _buffer(buffer_default_size) {}

    // 获取当前写入起始地址
    const char* GetWritePos() const { return Begin() + _writer_idx; }

    // 获取当前读取起始地址
    const char* GetReadPos() const { return Begin() + _reader_idx; }

    // 将读偏移指针向后移动
    void MoveReadBackward(uint64_t len)
    {
        if (len == 0) return;
        assert(len <= GetSizeOfReadableData());
        _reader_idx += len;
        LOG(DEBUG, "读指针向后移动 %ld, 偏移值为 %ld\n", len, _reader_idx);
    }

    // 将写偏移指针向后移动
    void MoveWriteBackward(uint64_t len)
    {
        if (len == 0) return;
        assert(len <= GetSizeAfterWrite());
        _writer_idx += len;
        LOG(DEBUG, "写指针向后移动 %ld, 偏移值为 %ld\n", len, _writer_idx);
    }

    // 获取可读数据大小
    uint64_t GetSizeOfReadableData() const { return _writer_idx - _reader_idx; }

    // 写入数据
    void Write(const void* data, uint64_t len)
    {
        if (len == 0) return;
        EnsureWriteSpace(len);
        void* dst = (void*)GetWritePos();
        const char* src = (const char*)data;
        // std::copy(pdata, pdata + len, GetWritePos());
        if (dst == memmove(dst, src, len))
        {
            LOG(DEBUG, "数据写入成功！\n");
        }
        else
        {
            LOG(ERROR, "数据写入失败！\n");
            return;
        }
        MoveWriteBackward(len);
    }

    void WriteString(const std::string& data)
    {
        Write(data.c_str(), data.size());
    }

    void WriteBuffer(const Buffer& data)
    {
        Write(data.GetReadPos(), data.GetSizeOfReadableData());
    }

    // 读取数据
    void Read(void* buf, uint64_t len)
    {
        assert(len <= GetSizeOfReadableData());
        // std::copy(GetReadPos(), GetReadPos() + len, pbuf);
        if (buf == memmove(buf, GetReadPos(), len))
        {
            LOG(DEBUG, "数据读取成功！\n");
        }
        else
        {
            LOG(ERROR, "数据读取失败！\n");
        }
    }

    void ReadAndPop(void* buf, uint64_t len)
    {
        Read(buf, len);
        MoveReadBackward(len);
    }

    void ReadAsString(std::string* str, uint64_t len)
    {
        assert(len <= GetSizeOfReadableData());
        str->resize(len);
        Read(&((*str)[0]), len);
    }

    void ReadAsStringAndPop(std::string* str, uint64_t len)
    {
        ReadAsString(str, len);
        MoveReadBackward(len);
    }

    char* FindCRLF()
    {
        return (char*)memchr(GetReadPos(), '\n', GetSizeOfReadableData());
    }

    void GetLine(std::string* str)
    {
        char* pos = FindCRLF();
        if (pos == nullptr)
        {
            LOG(WARNING, "查找 \\n 失败\n");
            return;
        }
        return ReadAsString(str, pos - GetReadPos() + 1);
    }

    void GetLineAndPop(std::string* str)
    {
        char* pos = FindCRLF();
        if (pos == nullptr)
        {
            LOG(WARNING, "查找 \\n 失败\n");
            return;
        }
        return ReadAsStringAndPop(str, pos - GetReadPos() + 1);
    }

    // 清空缓冲区
    void Clear()
    {
        _reader_idx = 0;
        _writer_idx = 0;
        LOG(INFO, "读写缓冲区清空成功！\n");
    }

    ~Buffer() {}

private:
    std::vector<char> _buffer;  // 使用 vector 进行内存空间管理
    uint64_t _reader_idx;       // 读偏移
    uint64_t _writer_idx;       // 读偏移
};
